<template>
  <div>
    <el-drawer
      :title="detailType === 'knowledgeUnit' ? knowledgeUnitName : crtRow.str"
      size="50%"
      :modal="false"
      :visible.sync="drawerVisible"
      :direction="drawerDirection"
      @close="contentEditFlag = false; drawerVisible = false">
      <el-button v-if="detailType === 'knowledgeUnit'" size="small" @click="editContent" v-html="contentEditFlag ? '保存' : '编辑'"></el-button>
      <div v-show="contentEditFlag" style="margin-top: 10px">
        <div style="width: 100px; display: inline-block; text-align: right; vertical-align: middle; ">知识单元名称: </div>
        <KindEditor style="width: 300px; display: inline-block; vertical-align: middle; " :content.sync="knowledgeUnitName" editor-type="Input"/>
      </div>
      <div  :style="{backgroundColor : contentEditFlag ? 'aliceblue' : 'antiquewhite'}" ref="contentDiv" :contenteditable="contentEditFlag" v-html="knowledgeUnitContent"></div>
    </el-drawer>
    <el-row>
      <el-col :span="16"
              style="overflow-x: auto; ">
        <div style="width: max-content; min-width: 100%; ">
          <el-row style="width: max-content; margin: 0px 5px; ">
            <el-button icon="el-icon-back"
                       size="small"
                       type="text"
                       @click="$router.go(-1)">返回</el-button>
            <div style="display: inline-block">|</div>
<!--            <el-button size="small" type="primary" style="width: 100px;" @click='unExpandAllNode'>折叠</el-button>-->
            <el-button v-for="(level,idx) in treeLevel"
                       :key="idx"
                       size="small"
                       class="buttonClass"
                       @click='expandTreeNode(level)'>展开{{CONST.INT_CHAR_ARRAY[level]}}级目录</el-button>
          </el-row>

          <el-row>
            <el-tree :key="forceUpdateKey"
                     ref="catalogTree"
                     :style="{height: treeHeight + 'px', marginLeft: '30px', overflowY: 'auto'}"
                     :expand-on-click-node="false"
                     render-after-expand
                     auto-expand-parent
                     show-checkbox
                     :check-strictly="true"
                     :data=catalogTreeData
                     :props="defaultProps"
                     @check-change="checkChange"
                     node-key="id"
                     :indent="160">
          <span slot-scope="{node, data}">
            <el-link @click.prevent="detail(data, 'catalogItem')"
                     v-html="node.label"
                     :title="node.label"
                     style="max-width: 170px; display: inline-block; text-overflow: ellipsis; overflow:hidden; "></el-link>
          </span>
            </el-tree>
          </el-row>
        </div>
      </el-col>
      <el-col :span="8"
              style="padding-left: 5px; ">
        <el-row>
          <div style="float: right">
            <div style="display: inline-block">请选择知识单元拆分层级:</div>
            <el-select size="small"
                       v-model="selectedLevel"
                       style="width: 60px;">
              <el-option v-for="(level,ids) in treeLevel"
                         :key="ids"
                         :value="level" />
            </el-select>
            <el-button size="small"
                       type="success"
                       @click='extractKnowledgeUnit'>提取知识</el-button>
          </div>
        </el-row>

        <el-row style="padding: 5px 0px; width: 100%; ">
          <el-input size="small"
                    v-model="keyWords"
                    placeholder="请输入知识单元名称搜索">
            <i class="el-input__icon el-icon-search"
               slot="prefix"></i>
          </el-input>
        </el-row>

        <el-row>
          <el-col>
            <u-table highlight-current-row
                     stripe
                     use-virtual
                     ref="knowledgeUnitTable"
                     :height="tableHeight"
                     render-after-expand
                     auto-expand-parent
                     show-checkbox
                     :check-strictly="true"
                     :data='filteredKnowledgeUnitList'
                     :props="defaultProps">
              <u-table-column align="center"
                              type="selection"
                              width="50">
              </u-table-column>
              <u-table-column align="center"
                              label="序号"
                              type="index"
                              width="50">
              </u-table-column>
              <u-table-column label="知识名称">
                <template slot-scope="scope">
                  <span v-html="scope.row.name"/>
                </template>
              </u-table-column>
              <u-table-column label="操作"
                              width="100">
                <template slot-scope="scope">
                  <span>
                    <el-link @click.prevent="detail(scope.row, 'knowledgeUnit')">详情</el-link>
                  </span>
                  <span>
                    <el-link type="danger"
                             @click.prevent="deleteKnowledgeUnit(scope.row)">删除</el-link>
                  </span>
                </template>
              </u-table-column>
            </u-table>
            <div style="float: right; ">
              <el-button size="small"
                         @click='cancelSelectedKnowledgeUnitArray'>撤销</el-button>
              <el-button size="small"
                         @click='insertList'
                         type="primary">保存</el-button>
              <el-button size="small"
                         @click='insertListAndReleased'
                         type="primary">保存并标注</el-button>
            </div>
          </el-col>
        </el-row>
      </el-col>
    </el-row>
  </div>
</template>

<script>
  import {mapState} from 'vuex'
  import {mapMutations} from 'vuex'
  export default {
    name: "ExtractKnowledgeUnit",
    data() {
      return {
        treeHeight: CONST.WORKSPACE_HEIGHT - 65,
        tableHeight: CONST.WORKSPACE_HEIGHT - 120,
        catalogTreeData: [],
        knowledgeUnitList: [],
        defaultProps: {
          label: 'str',
        },
        selectedLevel: 1,
        drawerVisible: false,
        knowledgeUnitName: '',
        knowledgeUnitContent: '',
        drawerDirection: 'ltr',
        treeLevel: 1,
        keyWords: '',
        detailType: '',
        crtRow: {},
        contentEditFlag: false,
      }
    },
    methods: {
      ...mapMutations(['forceUpdate']),
      async editContent() {
        if (this.contentEditFlag) {
          this.crtRow.content = this.$refs.contentDiv.innerHTML
          this.crtRow.name = this.knowledgeUnitName
          await this.updateKnowledgeUnitById(this.crtRow)
          this.drawerVisible = false
        }
        this.contentEditFlag = !this.contentEditFlag
      },
      async updateKnowledgeUnitById(tableRow) {
        if (tableRow.knowledgeUnitId) {
          await this.axios.post('/pmph/action/knowledgeUnit/updateById', {
            name: tableRow.name,
            bookId: tableRow.bookId,
            bookCatalogItemId: tableRow.id,
            content: tableRow.content,
            id: tableRow.knowledgeUnitId,
            status: tableRow.status,
          }).then(() => {
          })
        }
      },
      parseVoToKnowledgeUnit(knowledgeUnitList){
        for (let tableRow of this.knowledgeUnitList.filter(item => !item.knowledgeUnitId)) {
          let knowledgeUnit = {
            name: tableRow.name,
            bookId: tableRow.bookId,
            bookCatalogItemId: tableRow.id,
            bookCatalogPath: tableRow.bookCatalogPath,
            content: tableRow.content,
            id: tableRow.knowledgeUnitId,
            status: tableRow.status
          }
          knowledgeUnitList.push(knowledgeUnit)
        }
      },
      // 只有新增的, 修改的点击修改内容时已同步到后台;
      async insertList() {
        let knowledgeUnitList = []
        this.parseVoToKnowledgeUnit(knowledgeUnitList)
        await this.axios.post('/pmph/action/knowledgeUnit/insertList', knowledgeUnitList)
        this.selectKnowledgeUnitList()
      },
      async insertListAndReleased() {
        let knowledgeUnitList = []
        this.parseVoToKnowledgeUnit(knowledgeUnitList)
        // 计算 标注进度, 不可选目录项与全部目录项比值;
        let catalogList = Object.values(this.$refs.catalogTree.store.nodesMap)
        let catalogListLength = catalogList.length
        let extractedCatalogListLength = catalogList.filter(node => node.disabled).length
        let markedRate = (extractedCatalogListLength / catalogListLength).toFixed(2)
        // 新增本次提取的知识, 并吧本书的知识单元都设置为 released, 后端返回 本次修改状态的所有知识单元集合;
        await this.axios.post('/pmph/action/knowledgeUnit/insertListAndReleased' +
                                  '?bookId=' + this.$route.query.bookId +
                                  '&markedRate=' + markedRate, knowledgeUnitList)
          .then((response) => {
            this.$store.commit('setKnowledgeUnitList', response.data)
          })
        this.$router.push({
          path: '/mark/markKnowledgeUnit',
          query: {
            bookId: this.$route.query.bookId,
          }
        })
      },
      async detail(tableRow, type) {
        this.detailType = type
        this.crtRow = tableRow
        if (!tableRow.content) {
          await this.axios.get('/pmph/action/knowledgeUnit/selectContentByCatalogId', {
            params: {
              bookCatalogItemId: tableRow.id
            }
          }).then((response) => {
            debugger
              tableRow.content = response.data.unitContent
            })
        }
        if (type === 'knowledgeUnit') {
          this.drawerDirection = 'ltr'
        }
        else if (type === 'catalogItem') {
          this.drawerDirection = 'rtl'
        }
        this.knowledgeUnitContent = tableRow.content
        this.knowledgeUnitName = tableRow.name
        this.drawerVisible = true
      },
      deleteKnowledgeUnit(tableRow){
        this.$set(tableRow, 'disabled', false)
        this.knowledgeUnitList.remove(tableRow)
        if (tableRow.knowledgeUnitId) {
          this.axios.post('/pmph/action/knowledgeUnit/deleteById', {
            id: tableRow.knowledgeUnitId
          })
        }
      },
      cancelSelectedKnowledgeUnitArray(){
        for (let tableRow of this.$refs.knowledgeUnitTable.$refs.singleTable.selection) {
          this.deleteKnowledgeUnit(tableRow)
        }
      },
      extractKnowledgeUnit(){
        let checkedNodes = this.$refs.catalogTree.getCheckedNodes()
        if (checkedNodes.length === 0) {
          this.$message.warning('请选择要拆分的目录')
          return;
        }
        for(let data of checkedNodes) {
          let crtNode = this.$refs.catalogTree.getNode(data)
          this.recursiveExtractKnowledgeUnit(crtNode)
        }
        // 取消选中
        this.$refs.catalogTree.setCheckedNodes([])
        // 取消树节点选中会触发checkChange事件, 渲染完成后重新计算disabled属性
        // this.$nextTick(this.setCatalogTreeNodeDisabled) // watch knowledgeUnitList 改为 nextTick, 无需再次调用;
      },
      recursiveExtractKnowledgeUnit(node) {
        if (node.level < this.selectedLevel) {
          for(let subNode of node.childNodes) {
            this.recursiveExtractKnowledgeUnit(subNode)
          }
        }
        else if (node.level === this.selectedLevel) {
          if (!node.data.name) {
            node.data.name = UTIL.parseCatalogName2KnowledgeUnitName(node.data.str)
          }
          if (!node.data.bookCatalogPath) {
            node.data.bookCatalogPath = node.label
            let crtNode = node.parent
            while(crtNode.parent) {
              node.data.bookCatalogPath = crtNode.label + '/' + node.data.bookCatalogPath
              crtNode = crtNode.parent
            }
          }
          // 新提取的知识单元, 状态为temp;
          node.data.status = 0
          this.knowledgeUnitList.pushIfNotContains(node.data)
          this.$set(node.data, 'disabled', true)
        }
      },
      unExpandAllNode() {
        Object.values(this.$refs.catalogTree.store.nodesMap).forEach(node => node.expanded = false)
      },
      checkChange(data, props) {
        let that = this
        // 如果当前节点选中, 则子节点都不可选;
        if (props) {
          UTIL.recursiveForEachTreeNode(data.children, item => that.$set(item, 'disabled', true))
        }
        // 如果当前节点取消选中, 子节点需要重新计算;
        else {
          UTIL.recursiveForEachTreeNode(data.children, item => {
            // 父节点可选且未选中, 且当前节点未提取知识单元, 则当前节点才能重置为可选状态;
            if (!that.$refs.catalogTree.getNode(item.parentId).data.disabled
              && !that.$refs.catalogTree.getNode(item.parentId).checked
              // && that.$refs.catalogTree.getCheckedNodes().indexOf(item) === -1
              && that.knowledgeUnitList.indexOf(item) === -1) {
              that.$set(item, 'disabled', false)
            }
          })
        }
        // 递归设置父节点, 不可选;
        if(data.parentId) {
          let supNode = this.$refs.catalogTree.getNode(data.parentId)
          if (supNode) {
            this.recursiveSetSupTreeNodeDisabled(supNode.data)
          }
        }
        this.$forceUpdate()
      },
      expandTreeNode(level) {
        var checkedNodes = this.$refs.catalogTree.getCheckedNodes()
        if (checkedNodes.length === 0) {
          this.$message.warning('请选择要展开的目录')
          return;
        }
        this.unExpandAllNode()
        // 递归展开选中节点的父节点;
        for(let data of checkedNodes) {
          var crtNode = this.$refs.catalogTree.getNode(data)
          this.recursiveExpandSupNode(crtNode.parent)
        }
        // 递归展开选中节点子节点, 直至选中层级;
        for(let data of checkedNodes) {
          var crtNode = this.$refs.catalogTree.getNode(data)
          this.recursiveExpandSubNode(crtNode, level)
        }
      },
      recursiveExpandSupNode(node) {
        if (node) {
          node.expanded = true
          this.recursiveExpandSupNode(node.parent)
        }
      },
      recursiveExpandSubNode(node, level) {
        if (node.level < level) {
          node.expanded = true
          for(let subNode of node.childNodes) {
            this.recursiveExpandSubNode(subNode, level)
          }
        }
      },
    setTreeLevel () {
      let that = this
      UTIL.recursiveForEachTreeNode(this.catalogTreeData, node => that.treeLevel = Math.max(that.treeLevel, node.layer))
    },
    recursiveSetSupTreeNodeDisabled (item) {
      if (item) {
        // 如果本身未提取知识单元, 则需要根据子节点判断是否可选;
        if (this.knowledgeUnitList.indexOf(item) === -1) {
          // 查找子节点是否有可选的并且未选中的, 如果有, 那么父节点也就可选, 如果子节点都不可选, 则父节点也不可选;
          this.$set(item, 'disabled', item.children && !item.children.some(childItem => !childItem.disabled && !this.$refs.catalogTree.getNode(childItem).checked))
        }
        if (item.parentId) {
          let supNode = this.$refs.catalogTree.getNode(item.parentId)
          if (supNode) {
            this.recursiveSetSupTreeNodeDisabled(supNode.data)
          }
        }
        this.$forceUpdate()
      }
    },
    parseKnowledgeUnit2CatalogItem (knowledgeUnitList) {
      for (let knowledgeUnit of knowledgeUnitList) {
        let catalogItemNode = this.$refs.catalogTree.getNode(knowledgeUnit.bookCatalogItemId);
        if (catalogItemNode) {
          let catalogItem = catalogItemNode.data
          this.$set(catalogItem, 'disabled', true)
          this.$set(catalogItem, 'name', knowledgeUnit.name)
          this.$set(catalogItem, 'content', knowledgeUnit.content)
          this.$set(catalogItem, 'knowledgeUnitId', knowledgeUnit.id)
            this.$set(catalogItem, 'status', knowledgeUnit.status)
            this.knowledgeUnitList.push(catalogItem)
          }
        }
      },
      // 递归设置树节点是否可被选中;
      setCatalogTreeNodeDisabled() {
        // 遍历知识单元, 已有知识单元节点不可选中;
        // 知识单元数组, 和目录树公用一组数据;
        let that = this
        this.knowledgeUnitList.forEach(item => that.$set(item, 'disabled', true))
        // 向上层递归, 如果子目录都不可选, 则父级目录也不可选;
        this.knowledgeUnitList.forEach(this.recursiveSetSupTreeNodeDisabled)
        // 先序遍历, 向下层递归, 如果父节点不可选, 则子节点也都不可选;
        UTIL.recursiveForEachTreeNode(this.knowledgeUnitList, function (item) {
          if (item.disabled && item.children && item.children.length > 0) {
            item.children.forEach(child => that.$set(child, 'disabled', true))
          }
        })
      },
      selectKnowledgeUnitList(){
        // 查询目前已提取的知识单元;
        this.axios.get('/pmph/action/knowledgeUnit/selectListByBookId?bookId=' + this.$route.query.bookId)
          .then(response => {
            this.knowledgeUnitList = []
            this.parseKnowledgeUnit2CatalogItem(response.data)
            // 强制重新渲染;
            this.forceUpdate()
          })
    },
  },
    computed: {
      ...mapState(['forceUpdateKey']),
      // 按照关键字和状态过滤, 只展示暂存的;
      filteredKnowledgeUnitList() {
        if (this.keyWords) {
          return this.knowledgeUnitList
            .filter(item => item.status === 0)
            .filter(item => item.name.search(this.keyWords) !== -1)
        }
        return this.knowledgeUnitList.filter(item => item.status === 0)
      }
    },
    created() {
      this.axios.get('/pmph/action/book/selectBookTree?bookId=' + this.$route.query.bookId)
        .then((response) => {
          this.catalogTreeData = response.data
          //目录layer字段代表层级, 查找最深层级;
          this.setTreeLevel()
          this.selectKnowledgeUnitList()
        })
    },
    watch: {
      knowledgeUnitList() {
        this.$nextTick(this.setCatalogTreeNodeDisabled)
      }
    }
  }
</script>

<style scoped>
  .buttonClass {
    width: 149px;
  }

  .inline {
    display: inline-block;
  }

  .reorder-button {
    width: 20px;
    height: 20px;
    border-radius:10px;
    padding: 0;
    margin: 0;
  }
  /deep/ .el-tree-node.is-expanded > .el-tree-node__children {
      display: inline;
  }
  /deep/ .el-drawer__body {
    overflow: auto;
    margin: 0px 20px;
  }
</style>
